/*********************************************************************
 * Software License Agreement
 *
 * Copyright (C) 2010 Cross The Road Electronics.  All rights
 * reserved.
 *
 * Cross The Road Electronics (CTRE) licenses to you the right to 
 * use, copy, modify, merge, publish, distribute, sublicense, and/or 
 * sell copies of the Software ONLY when in use with CTRE's 2CAN 
 * Ethernet CAN Gateway.
 *
 * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
 * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
 * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
 * CROSS THE ROAD ELECTRONICS BE LIABLE FOR ANY INCIDENTAL, SPECIAL, 
 * INDIRECT OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
 * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
 * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
 * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
 * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
 * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
 *
********************************************************************/
#include "OS_Event.h"

#ifdef OS_ABSTRACTION_VISUAL_STUDIO
	
	OS_Event::OS_Event(const TCHAR * name, bool bManualReset)
	{
		m_hThread = CreateEvent(	NULL,               // default security attributes
									bManualReset,               // manual-reset event
									FALSE,              // initial state is nonsignaled
									//name  // object name
									0
									); 
	}
	OS_Event::OS_Event()
	{
		m_hThread = CreateEvent(	NULL,               // default security attributes
									true,               // manual-reset event
									FALSE,              // initial state is nonsignaled
									//name  // object name
									0
									); 
	}


	OS_Event::~OS_Event()
	{
		CloseHandle(m_hThread);
		m_hThread = 0;
	}

	void OS_Event::Signal()
	{
		SetEvent(m_hThread);
	}

	void OS_Event::Reset()
	{
		ResetEvent(m_hThread);
	}
	bool OS_Event::IsSignaled()
	{
		switch(WaitForSingleObject(m_hThread,0))
		{
			case WAIT_TIMEOUT:
				return false;

			case WAIT_ABANDONED:
			case WAIT_OBJECT_0:
			case WAIT_FAILED :
				return true;
		}
		return true;
	}
	bool OS_Event::WaitUntilSignaled()
	{
		switch(WaitForSingleObject(m_hThread,INFINITE))
		{
			case WAIT_TIMEOUT:
				return false;

			case WAIT_ABANDONED:
			case WAIT_OBJECT_0:
			case WAIT_FAILED :
				return true;
		}
		return true;
	}
	bool OS_Event::WaitUntilSignaled(uint32_t timeout_ms)
	{
		switch(WaitForSingleObject(m_hThread,timeout_ms))
		{
			case WAIT_TIMEOUT:
				return false;

			case WAIT_ABANDONED:
			case WAIT_OBJECT_0:
			case WAIT_FAILED :
				return true;
		}
		return true;
	}
#endif // OS_ABSTRACTION_VISUAL_STUDIO



#if defined(OS_ABSTRACTION_VXWORKS)
	
#include "OS_Semaphore.h"
	
	OS_Event::OS_Event(const TCHAR * name, bool bManualReset)
	{
		this->bManualReset = bManualReset;
		sem = new OS_Semaphore();
		bSignaled = false;
	}


	OS_Event::~OS_Event()
	{
		delete sem;
		sem = 0;
	}

	void OS_Event::Signal()
	{
		sem->Lock();
		bSignaled = true;
		sem->Unlock();
	}

	void OS_Event::Reset()
	{
		sem->Lock();
		bSignaled = false;
		sem->Unlock();
	}
	bool OS_Event::IsSignaled()
	{		
		bool retval;
		
		sem->Lock();
		retval = bSignaled;
		
		if(retval)
			if(!bManualReset)
			{
				bSignaled = false;
			}
		sem->Unlock();
		
		return retval;
	}
	bool OS_Event::WaitUntilSignaled()
	{
		return WaitUntilSignaled(~0);
	}
	bool OS_Event::WaitUntilSignaled(uint32_t timeout_ms)
	{
		while(!IsSignaled() && (timeout_ms > 0) )
		{
			taskDelay(10);

			if(timeout_ms < 10)
				timeout_ms = 0;
			else
				timeout_ms -= 10;
		}
		return true;
	}
#endif

